package list.p1_arraylist;


import lombok.Getter;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

/**
 * 未实现泛型，只能存储int类型
 * 默认初始容量为10
 * 默认扩容为原来的1.5倍
 */
@Getter
public class MyArrayList implements Iterable<Integer>{
    private static final int DEFAULT_CAPACITY = 10;
    private int[] array;
    private int size;
    private int capacity;

    public MyArrayList() {
        this.capacity = DEFAULT_CAPACITY;
        this.array = new int[]{};
    }

    public int get(int index) {
        if (index < 0 || index >= size) {
            throw new PosIllegal("index out of bounds");
        }
        return array[index];
    }

    private void checkAndGrow() {
        if (size == 0) array = new int[capacity];
        if (size == capacity) {
            capacity += capacity >> 1;
//            int[] newArray = new int[capacity];
//            System.arraycopy(array,0,newArray,0,size);
//            array = newArray;
            array = Arrays.copyOf(array, capacity);
        }
    }
    public void add(int value) {
        add(value, size);
    }

    public void add(int value, int index) {
        if (size == 0) {
            array = new int[capacity];
        }
        if (index < 0 || index > size) {
            throw new PosIllegal("index out of bounds");
        }
        size++;
        checkAndGrow();
        System.arraycopy(array, index, array, index + 1,  size - index - 1);
        array[index] = value;
    }

    public void addAll(int[] values) {
        for (int value : values) {
            add(value, size);
        }
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void remove(int index) {
        if (index < 0 || index >= size) {
            throw new PosIllegal("index out of bounds");
        }
        System.arraycopy(array, index + 1, array, index, size-- - index - 1);
    }

    public void clear() {
        size = 0;
    }

    public boolean contains(int value) {
        for (int i = 0; i < size; i++) {
            if (equals(value, i)) {
                return true;
            }
        }
        return false;
    }

    public boolean equals(int value,  int index) {
        return this.get(index) == value;
    }

    public int find(int value) {
        for (int i = 0; i < size; i++) {
            if (equals(value, i)) {
                return i;
            }
        }
        return -1;
    }

    public void set(int value, int index) {
        if (index < 0 || index >= size) {
            throw new PosIllegal("index out of bounds");
        }
        array[index] = value;
    }

    public void foreach(Consumer<Integer> consumer) {
        for (int i = 0; i < size; i++) {
            consumer.accept(array[i]);
        }
    }

    public IntStream stream() {
        return IntStream.of(Arrays.copyOfRange(array, 0, size));
    }

    public void sort(Comparator<Integer> comparator) {
        for (int i = 0; i < size - 1; i++) {
            for (int j = i + 1; j < size; j++) {
                if (comparator.compare(array[i], array[j]) > 0) {
                    int temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(String.format(i == size - 1 ? "%d" : "%d, ", array[i]));
        }
        return sb.append("]").toString();
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<>() {
            int i = 0;
            @Override
            public boolean hasNext() {
                return i < size;
            }

            @Override
            public Integer next() {
                return array[i++];
            }
        };
    }
}
